﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;

namespace Universe.WCF.Behaviors
{
    public class TrafficDefaultInfoWriter
    {
        private static Thread _Thread;
        private static ManualResetEvent _StopWriting;
        private static object Sync = new object();

        public static void TurnWritingOn(string fileName, TimeSpan interval)
        {
            if (_Thread != null)
                TurnWritingOff();

            lock (Sync)
            {
                ManualResetEvent started = new ManualResetEvent(false);
                _Thread = new Thread(
                    delegate()
                        {
                            started.Set();
                            _StopWriting = new ManualResetEvent(false);
                            while (true)
                            {
                                DateTime start = DateTime.Now;

                                ExecWrite(fileName);

                                TimeSpan elapsed = DateTime.Now - start;
                                TimeSpan sleep = interval - elapsed;
                                if (sleep > interval)
                                    sleep = interval;

                                if (sleep < TimeSpan.Zero)
                                    sleep = TimeSpan.Zero;

                                if (_StopWriting.WaitOne(sleep, false))
                                    break;
                            }
                        });

                _Thread.IsBackground = true;
                _Thread.Start();
                started.WaitOne();
            }
        }

        private static void ExecWrite(string fileName)
        {
            try
            {
                Directory.CreateDirectory(Path.GetDirectoryName(fileName));
            }
            catch
            {
            }

            try
            {
                Encoding enc = null;
                try
                {
                    enc = Encoding.GetEncoding(1252);
                }
                catch
                {
                    enc = Encoding.ASCII;
                }

                using (FileStream fs = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.Read))
                using (StreamWriter wr = new StreamWriter(fs, enc))
                {
                    string serverStatisticReport;
                    lock (TrafficDefaultInfo.ServerStatistic)
                        serverStatisticReport = TrafficDefaultInfo.ServerStatistic.ToPlainReport();

                    wr.WriteLine("SERVER");
                    wr.WriteLine(serverStatisticReport);
                    wr.WriteLine();

                    string clientStatisticReport;
                    lock (TrafficDefaultInfo.ClientStatistic)
                        clientStatisticReport = TrafficDefaultInfo.ClientStatistic.ToPlainReport();

                    wr.WriteLine("CLIENT");
                    wr.WriteLine(clientStatisticReport);
                }
            }
            catch
            {
            }
        }

        public static void Flush(string fileName)
        {
            ExecWrite(fileName);
        }

        public static void TurnWritingOff()
        {
            if (_Thread != null)
                lock (Sync)
                    if (_Thread != null)
                    {
                        _StopWriting.Set();
                        if (!_Thread.Join(1000))
                            _Thread.Abort();

                        _StopWriting = null;
                        _Thread = null;
                    }
        }

    }
}